package com.ymatou.iapi.optrade.testcase;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import com.ymatou.iapi.optrade.parameter.enums.CancelOrderTypeEnum;
import com.ymatou.iapi.optrade.parameter.enums.LogisticsTypeEnum;
import com.ymatou.iapi.optrade.parameter.req.BatchCancelOrderReq;
import com.ymatou.iapi.optrade.resp.TradingServiceResp;
import com.ymatou.iapi.optrade.resp.Order;
import com.ymatou.iapi.optrade.service.BatchCancelOrderCall;
import com.ymatou.iapi.optrade.service.PrepaidCardService;
import com.ymt.core.tool.Logger;
import com.ymt.utils.annotation.TestCase;
import com.ymt.utils.annotation.TestSuite;
import com.ymt.utils.tag.P1;
import com.ymttest.business.service.PayGateWayCallService;
import com.ymttest.business.service.YMTTrading.TradingCallService;
import com.ymttest.business.service.YMTTrading.TradingPlaceOrderCallService;
import com.ymttest.database.sharding.db.sharding.model.OrderPo;
import com.ymttest.database.sharding.db.sharding.model.UserRefundFundDetailPo;
import com.ymttest.database.sharding.db.sqlwapper.OrderShardingWapper;
import com.ymttest.utils.DataUtil;
import com.ymttest.utils.constant.ECode;

/**
 * 批量取消订单 FreeMaker Template自动生成代码
 */
@TestSuite
public class Ts_BatchCancelOrder {

	private static BatchCancelOrderReq batchCancelOrderReq;
	private static BatchCancelOrderCall batchcancelordercall;
	
	private static OrderShardingWapper orderShardingWapper = new OrderShardingWapper();

	@BeforeClass
	public static void setUp() {
		Logger.createResultFile("批量取消订单");
	}

	@Before
	public void caseUp() {

		batchCancelOrderReq = new BatchCancelOrderReq();
		batchcancelordercall = new BatchCancelOrderCall();
	}

	@AfterClass
	public static void tearDown() {
		Logger.generateResult(batchcancelordercall.getOpurl());
		orderShardingWapper.activeDeadCommunicationsLink(orderShardingWapper);
	}

	@After
	public void caseDown() {
		Logger.end();
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_BatchCancelOrder_001() {
		Logger.start(true, "订单支付前,买家批量取消订单成功,订单状态为13 卖家取消订单");
		try {
			// 参数
			Logger.comment("前置数据准备");
			ArrayList<Long> OrderIdList = new ArrayList<Long>();

			long sellerId = 0;

			// 创建订单
			for (int i = 0; i < 2; i++) {

				TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
						.placeOrderWithLuxury(false);

				OrderPo order = placeOrderResp.getOrderList().get(0)
						.getOrderPo();

				long orderId = order.getOrderId();
				sellerId = order.getSellerId();
				OrderIdList.add(orderId);

			}
			Logger.comment("前置数据准备结束");
			batchCancelOrderReq.setOrderIdList(OrderIdList);
			batchCancelOrderReq.setCancelReason("自动化测试取消订单");
			batchCancelOrderReq
					.setCancelType(CancelOrderTypeEnum.SELLER_CANCEL_ORDER);
			// 卖家ID
			batchCancelOrderReq.setUserId(sellerId);
			// 发送请求
			batchcancelordercall.setData(batchCancelOrderReq);
			batchcancelordercall.callService();
			Logger.verifyEquals(ECode.SUCCESS, batchcancelordercall.getCode(),
					"验证Code");
			
			// 验证数据库
			int size = OrderIdList.size();
			for (int i = 0; i < size; i++) {
				long orderId = batchCancelOrderReq.getOrderIdList().get(i);

				Ts_CancelOrder.verifyOrderStatus(13, orderId,
						batchCancelOrderReq.getUserId(),
						batchCancelOrderReq.getCancelType(),
						batchCancelOrderReq.getCancelReason());
			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_BatchCancelOrder_002() {
		Logger.start(true, "订单支付后,批量取消订单成功,退款原路返回");
		try {
			// 参数
			Logger.comment("前置数据准备");
			ArrayList<Long> OrderIdList = new ArrayList<Long>();

			TradingServiceResp placeOrderResp = Ts_CancelOrder
					.placeOrder5(false);

			Long userId = placeOrderResp.getUserId();

			placeOrderResp.getOrderList().forEach(
					order -> OrderIdList.add(order.getOrderId()));

			Logger.comment("前置数据准备结束");

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			BigDecimal useAccountAmount = BigDecimal.ZERO;

			Long thirdTradingId = TradingCallService.payOrder(userId,
					useAccountAmount, placeOrderResp.getMainOrderId(), "13");

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("13", thirdTradingId.toString(),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Logger.comment("前置数据准备结束");

			Thread.sleep(4000);

			batchCancelOrderReq.setOrderIdList(OrderIdList);
			batchCancelOrderReq.setCancelReason("自动化测试取消订单");
			batchCancelOrderReq
					.setCancelType(CancelOrderTypeEnum.BUYER_CANCEL_ORDER);
			// 卖家ID
			batchCancelOrderReq.setUserId(userId);
			// 发送请求
			batchcancelordercall.setData(batchCancelOrderReq);
			batchcancelordercall.callService();
			Logger.verifyEquals(ECode.SUCCESS, batchcancelordercall.getCode(),
					"验证Code");
			// 验证数据库

			for (int i = 0; i < OrderIdList.size(); i++) {
				long orderId = batchCancelOrderReq.getOrderIdList().get(i);

				Ts_CancelOrder.verifyOrderStatus(12, orderId,
						batchCancelOrderReq.getUserId(),
						batchCancelOrderReq.getCancelType(),
						batchCancelOrderReq.getCancelReason());

				//订单表(order)
				OrderPo orderPo = orderShardingWapper
						.selectOrderbyOrderId(orderId);

				//用户退款资金详情表（user_refund_fund_detail）
				UserRefundFundDetailPo userRefundFundDetailPo = orderShardingWapper
						.selectUserRefundFundDetailByBizno(String
								.valueOf(orderId));

				UserRefundFundDetailPo expectUserRefundFundDetailPo = new UserRefundFundDetailPo();

				expectUserRefundFundDetailPo.setPaymentId(Long
						.valueOf(thirdTradingId));
				expectUserRefundFundDetailPo.setAccountRefundStatus(-1);
				expectUserRefundFundDetailPo.setBizType(2);
				expectUserRefundFundDetailPo.setThirdpartyAmount(orderPo
						.getThirdpartyPaidAmount());
				expectUserRefundFundDetailPo.setThirdpartyRefundStatus(3);
				expectUserRefundFundDetailPo.setRetryTimes(0);
				expectUserRefundFundDetailPo.setMemo("0");
				expectUserRefundFundDetailPo.setAccountAmount(orderPo
						.getAccountPaidAmount());
				expectUserRefundFundDetailPo.setOrderId(orderId);

				Ts_CancelOrder.verifyUserRefundFundDetailDb(
						expectUserRefundFundDetailPo, userRefundFundDetailPo);

			}
		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_BatchCancelOrder_003() {
		Logger.start(true, "批量取消订单,其中有订单不能取消");
		try {
			// 参数
			Logger.comment("前置数据准备");
			ArrayList<Long> OrderIdList = new ArrayList<Long>();

			TradingServiceResp placeOrderResp = Ts_CancelOrder
					.placeOrder5(false);

			Long userId = placeOrderResp.getUserId();

			placeOrderResp.getOrderList().forEach(
					order -> OrderIdList.add(order.getOrderId()));

			Logger.comment("前置数据准备结束");

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			TradingCallService.payOrder(userId, totalPrice,
					placeOrderResp.getMainOrderId());

			long sellerId = placeOrderResp.getOrderList().get(0).getSellerId();

			long orderId = placeOrderResp.getOrderList().get(0).getOrderId();

			//接单
			TradingCallService.sellerAcceptOrder(sellerId, orderId);

			Logger.comment("前置数据准备结束");

			batchCancelOrderReq.setOrderIdList(OrderIdList);
			batchCancelOrderReq.setCancelReason("自动化测试取消订单");
			batchCancelOrderReq
					.setCancelType(CancelOrderTypeEnum.BUYER_CANCEL_ORDER);
			// 卖家ID
			batchCancelOrderReq.setUserId(userId);
			// 发送请求
			batchcancelordercall.setData(batchCancelOrderReq);
			batchcancelordercall.callService();
			Logger.verifyEquals(ECode.FAILED201,
					batchcancelordercall.getCode(), "验证Code");
			Logger.verifyEquals("102", batchcancelordercall.getBCode(),
					"验证bcode");
			Logger.verifyEquals(
					String.format("买家取消订单%s状态不匹配", orderId),
					batchcancelordercall.getMsg(), "验证msg");

		} catch (Exception e) {
			Logger.fail(e);
		}
	}

	@Test
	@Category(P1.class)
	@TestCase
	public void Tc_BatchCancelOrder_004() {
		Logger.start(true, "使用了预付卡订单,余额+第三方支付后，取消订单");
		try {
			Logger.comment("准备前置数据");

			ArrayList<Long> OrderIdList = new ArrayList<Long>();

			TradingServiceResp placeOrderResp = PrepaidCardService
					.placeOrder2(false);

			Long userId = placeOrderResp.getUserId();
			long tradingId = placeOrderResp.getTradingId();

			BigDecimal totalPrice = placeOrderResp.getPayableAmount();

			// 用余额支付
			BigDecimal useAccountAmount = new BigDecimal(10);

			// 买家付款
			Long thirdTradingId = TradingCallService.payOrder(userId,
					useAccountAmount, tradingId, "13");

			// 支付网关支付回调交易
			PayGateWayCallService.notifyCall("13",
					String.valueOf(thirdTradingId),
					totalPrice.subtract(useAccountAmount).toString(),
					userId.intValue());

			Thread.sleep(5000);

			Logger.comment("准备前置数据结束");

			placeOrderResp.getOrderList().forEach(
					order -> OrderIdList.add(order.getOrderId()));

			batchCancelOrderReq.setOrderIdList(OrderIdList);
			batchCancelOrderReq.setCancelReason("自动化测试取消订单");
			batchCancelOrderReq
					.setCancelType(CancelOrderTypeEnum.BUYER_CANCEL_ORDER);
			// 卖家ID
			batchCancelOrderReq.setUserId(userId);
			// 发送请求
			batchcancelordercall.setData(batchCancelOrderReq);
			batchcancelordercall.callService();

			Logger.verifyEquals(ECode.SUCCESS, batchcancelordercall.getCode(),
					"验证Code");

			Thread.sleep(2000);

			// 验证数据库

			int size = OrderIdList.size();

			for (int i = 0; i < size; i++) {

				long orderId = batchCancelOrderReq.getOrderIdList().get(i);

				Ts_CancelOrder.verifyOrderStatus(12, orderId,
						batchCancelOrderReq.getUserId(),
						batchCancelOrderReq.getCancelType(),
						batchCancelOrderReq.getCancelReason());

				// 订单表(order)
				OrderPo ymtOrders = orderShardingWapper.selectOrderbyOrderId(orderId);

				UserRefundFundDetailPo userRefundFundDetailPo = orderShardingWapper
						.selectUserRefundFundDetailByBizno(String
								.valueOf(orderId));

				DataUtil.verifyDateEquals(ymtOrders.getCardAmount(),
						PrepaidCardService.getCardEntry(userId.intValue(),
								String.valueOf(orderId)), "校验取消订单退回的预付卡金额");

				BigDecimal refundAmount = userRefundFundDetailPo
						.getAccountAmount().add(
								userRefundFundDetailPo.getThirdpartyAmount());

				DataUtil.verifyDateEquals(ymtOrders.getPayableAmount(),
						refundAmount, "校验取消订单资金原路退回");

			}

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	//24646270在风控系统中被设置了黑名单，这个用户支付的订单全部会被风控取消
	//风控取消的订单优惠券不返还
	@Test
	@Category(P1.class)
	@TestCase
	@Ignore
	public void Tc_BatchCancelOrder_005() {
		Logger.start(true, "支付之后，风控批量取消订单");
		try {
			Logger.comment("前置数据准备");
			
			//下单
			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithThreeProcutInTwoOrder(true, BigDecimal.ZERO,
							24646270, LogisticsTypeEnum.OVERSEAS_DELIVERY);
			//支付订单
			TradingCallService.payOrder(placeOrderResp.getUserId(), placeOrderResp.getPayableAmount(), 
					placeOrderResp.getTradingId());
			
			Logger.comment("前置数据准备结束");

			List<Order> orderIdList = placeOrderResp.getOrderList();
			int size = orderIdList.size();
			Thread.sleep(3000);
			for (int i = 0; i < size; i++) {
				long orderId = orderIdList.get(i).getOrderPo().getOrderId();

				Ts_CancelOrder.verifyOrderStatus(18, orderId,
						-1,
						CancelOrderTypeEnum.RISKCONTROL_CANCEL_ORDER,
						"风控系统自动取消订单");
			}

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
	
	@Test
	@Category(P1.class)
	@TestCase
	@Ignore
	public void Tc_BatchCancelOrder_006() {
		Logger.start(true, "支付之后，多买手多订单风控批量取消订单");
		try {
			Logger.comment("前置数据准备");
			
			//下单
			TradingServiceResp placeOrderResp = TradingPlaceOrderCallService
					.placeOrderWithSixProcutAndFourOrdersInTwoSeller(true,
							BigDecimal.ZERO, 24646270);
			//支付订单
			TradingCallService.payOrder(placeOrderResp.getUserId(), placeOrderResp.getPayableAmount(), 
					placeOrderResp.getTradingId());
			
			Logger.comment("前置数据准备结束");

			List<Order> orderIdList = placeOrderResp.getOrderList();
			int size = orderIdList.size();
			Thread.sleep(3000);
			for (int i = 0; i < size; i++) {
				long orderId = orderIdList.get(i).getOrderPo().getOrderId();

				Ts_CancelOrder.verifyOrderStatus(18, orderId,
						-1,
						CancelOrderTypeEnum.RISKCONTROL_CANCEL_ORDER,
						"风控系统自动取消订单");
			}

		} catch (Exception e) {
			Logger.fail(e);
		}
	}
}
